package com.xg.util.export;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.xg.model.entity.OneData;
import com.xg.model.entity.TwoData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * Excel导出工具类（优化版）
 * 优化点：
 * 1. 简化数据结构，避免存储冗余数据
 * 2. 优化样式处理器的初始化
 */
public class ExcelExporter {

    private static final Logger logger = LoggerFactory.getLogger(ExcelExporter.class);

    /**
     * 不使用模板的Excel导出方法（优化版）
     */
    public static void exportWithoutTemplate(String fileName, List<SheetData<?>> sheetDataList) {
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();

        try (ServletOutputStream out = response.getOutputStream()) {
            // 设置响应头
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" +
                    URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString()));

            // 创建Excel写入器，并注册列宽处理器
            ExcelWriter excelWriter = EasyExcel.write(out)
                    .autoCloseStream(true)
                    .build();

            // 处理每个Sheet
            for (SheetData<?> sheetData : sheetDataList) {
                String sheetName = sheetData.getSheetName();
                List<?> dataList = sheetData.getDataList();
                String head = sheetData.getHead();
                Class<?> entityClass = sheetData.getEntityClass();

                // 1. 获取实体类字段（含@ExcelProperty和@ColumnWidth注解）
                List<Field> entityFields = getEntityFields(entityClass);
                // 2. 生成表头时，使用实体类字段顺序（确保与列索引对应）
                List<String> exportField = getExportField(entityFields);
                List<List<String>> headList = uploadExcelHead(exportField, head);
                // 动态计算表头行数（关键修改点）
                int headerRows;
                if (entityClass == OneData.class) {
                    headerRows = headList.isEmpty() ? 0 : headList.get(0).size() - 1;
                } else if (entityClass == TwoData.class) {
                    headerRows = headList.isEmpty() ? 0 : headList.get(0).size();
                } else {
                    // 默认情况，根据实际需求调整
                    headerRows = headList.isEmpty() ? 0 : headList.get(0).size() - 1;
                }

                // 3. 创建自定义列宽处理器，传入字段信息（关键：关联列索引与字段）
                CustomColumnWidthHandler columnWidthHandler = new CustomColumnWidthHandler(entityFields);
                // 创建样式处理器
                ExcelStyleHandler styleHandler = new ExcelStyleHandler(dataList, entityClass, headerRows);

                // 4. 创建Sheet并注册所有处理器
                WriteSheet writeSheet = EasyExcel.writerSheet(sheetName)
                        .head(headList)
                        .registerWriteHandler(styleHandler)
                        .registerWriteHandler(columnWidthHandler) // 注册列宽处理器
                        .build();

                // 写入数据
                if (!dataList.isEmpty()) {
                    excelWriter.write(dataList, writeSheet);
                }
            }

            // 完成导出
            excelWriter.finish();

        } catch (IOException e) {
            logger.error("Excel导出失败: {}", e.getMessage());
        }
    }

    // 辅助方法：获取实体类字段（含@ExcelProperty注解的字段，按声明顺序）
    private static List<Field> getEntityFields(Class<?> entityClass) {
        List<Field> fields = new ArrayList<>();
        for (Field field : entityClass.getDeclaredFields()) {
            if (field.isAnnotationPresent(ExcelProperty.class)) {
                fields.add(field); // 只保留有@ExcelProperty的字段（与表头列对应）
            }
        }
        return fields;
    }

    private static List<List<String>> uploadExcelHead(List<String> name, String condition) {
        List<List<String>> result = new ArrayList<>();
        for (int i = 0; i < name.size(); i++) {
            List<String> head = new ArrayList<>();
            head.add("内部文件 不得违规外传");
            head.add(condition); // 第二级表头为 condition
            head.add(name.get(i)); // 第三级表头为字段名
            result.add(head);
        }
        return result;
    }

    // 优化getExportField：基于字段列表获取ExcelProperty的值
    private static List<String> getExportField(List<Field> entityFields) {
        List<String> exportFields = new ArrayList<>();
        for (Field field : entityFields) {
            ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
            exportFields.add(annotation.value()[0]);
        }
        return exportFields;
    }
}